#ifndef SELF_DEFINE_FUNCTIONS_H_INCLUDED
#define SELF_DEFINE_FUNCTIONS_H_INCLUDED


#include "./CEC2013/cec2013.h"
#include <math.h>
#include <boost/random.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/cauchy_distribution.hpp>
#include <boost/random/normal_distribution.hpp>
#include <boost/random/uniform_real.hpp>
#include <vector>


using namespace std;

const int timesOfRun = 51;


const double epsilon_set[] = {1e-1,1e-2,1e-3,1e-4,1e-5};
const int epsilon_set_size = 5;


struct NewType
{
    double data;
    int id;
};




bool Compare_NewType( NewType data1, NewType data2 );

double Fitness ( double *particle, int &Fes, CEC2013 *pFunc );

void Popupation_Fitness( double **population, int population_size, int &Fes, double *result, CEC2013 *pFunc );

double Distance( double *vector1, vector<double> vector2, int dim );

double Distance( double *vector1, double *vector2, int dim );

void Get_Seeds( double **population, double *population_results, int population_size, int dim, vector<double> &seed_fitness, double radius );

int How_Many_Global_Optima( vector<double> seed_fitness, double epsilon, CEC2013 *pFunc );

int Compute_Global_Optima_Found( double **population, double *population_results, int population_size, int dim, double epsilon, CEC2013 *pFunc );

void Update_Dist( double **dist, double *temp_dist, int closet_individual, int population_size );

void Dist_All_to_All( double **population, double **dist, int population_size, int dim );

void Dist_Individual_to_All( double *dist, double *individual, double **population, int population_size, int dim );

void Get_Nearest_M_Individuals( double *dist, int *Nearest_M, int population_size, int n_nearest );

int Close_Particle( double *child, double **population, int population_size, int dim );

int Close_Particle( double *dist,  int population_size );

void Sort_Population_Dist( double *dist, int *sorted_index, int population_size );

void Sort_Population_Fitness( double *population_results, int *sorted_index, int population_size );

void Get_Nearest_M_Individuals( double *dist, bool *flag, int *Nearest_M, int population_size, int n_nearest );

void Species( double *reference_point, double **population, int **species, double **dist,
              int species_num, int N_nearest, int last_species_size, int population_size, int dim );

void Get_Seed_Location( int *seed_location, double *population_results, int **species, int species_num, int speices_size, int last_species_size );

void Mean_Std( double *mean_value, double *std_value, double *species, double **population, int species_size, int dim );

void Mean( double *mean_value, double *species, double **population, int species_size, int dim );

void Species_Evolve_Gaussian( int *species, double **population, double **child, double *LBound, double *UBound,
                     int dim, int species_size, double std_factor );

void Species_Evolve_Cauchy( int *species, double **population, double **child, double *LBound, double *UBound,
                     int dim, int species_size, double std_factor );

void Evolve_Gaussian( int **species, double **population, double **child, double *LBound, double *UBound,
             int dim, int species_num, int n_nearest,int last_species_size, double std_factor );

void Evolve_Cauchy( int **species, double **population, double **child, double *LBound, double *UBound,
             int dim, int species_num, int n_nearest,int last_species_size, double std_factor );

void Evolve_Cauchy_Gaussian( int **species, double **population, double **child, double *LBound, double *UBound,
             int dim, int species_num, int n_nearest,int last_species_size, double std_factor, double cauchy_gaussian_prob );

void Selection( double **population, double **child, double **dist, double *population_results, double *child_results,
                int population_size, int dim );

void Seed_Local_Prob( double *seed_local_prob, int *seed_location, double *population_results, int species_num );

void Generate_Reference_Point( double *reference_point, double *LBound, double *UBound, int dim );

void Local_Species_Evolve(  double **population, double *population_results, double *LBound, double *UBound, int seed_location,
                     int dim,  double local_std_value , int &Fes, CEC2013 *pFun, int sample_num );

void Local_Evolve(  double **population, double *population_results, double *LBound, double *UBound, double *seed_local_prob, int *seed_location,
                    int dim, int species_num,  double local_std_value, int &Fes, CEC2013 *pFun, int sample_num );


void Sort_Species( int *species, double *population_results, int *sorted_index, int species_size );

#endif // SELF_DEFINE_FUNCTIONS_H_INCLUDED
